import { _decorator, Component, Node, instantiate, Vec3, AnimationComponent } from 'cc';
import { Constants } from '../Data/Constants';
import { Utils } from '../Data/Utils';
import { UIManager } from '../UI/UIManager';
import { BulletView } from './BulletView';
import { Monster } from './Monster';
import { MonsterView } from './MonsterView';
import { PlayerView } from './PlayerView';
const { ccclass, property } = _decorator;

/********  战斗管理器，用于创建和管理敌人，输赢的判断等等   **********/

@ccclass('BattleManager')
export class BattleManager extends Component {
    @property({
        type:[Node],
        displayOrder:1
    })
    //包含所有敌人预物体的数组.
    enemyPrefabArray:Node[] = [];

    @property({
        type:Node,
        displayOrder:2
    })
    //所有复制出来的敌人的父亲.
    enemyParent:Node = null;

    @property({
        type:PlayerView,
        displayOrder:3,
    })
    //玩家角色身上的视图类组件.
    playerView:PlayerView = null;

    @property({
        type:AnimationComponent,
        displayOrder:4,
    })
    //摄像机身上的动画组件.
    camAnimationComp:AnimationComponent = null;

    @property({
        type:Node,
        displayOrder:5,
    })
    //子弹预物体.
    bulletPrefab:Node = null;

    @property({
        type:Node,
        displayOrder:6,
    })
    //所有子弹的父亲.
    bulletParent:Node = null;

    @property({
        type:Node,
        displayOrder:7,
    })
    //武器节点.
    weaponNode:Node = null;

    //怪物出生的范围.
    private _xMin = -15;
    private _xMax = 15;
    private _zMin = -45;
    private _zMax = -35;

    //战斗中，同屏存在的最大的敌人数量.
    private _maxEnemyNum = 15;
    //复制敌人的间隔.
    private _enemyCreateInterval = 0.2;
    //所有复制的敌人，都保存在此数组中.
    private _allEnemies:Monster[] = [];
    //游戏是否结束.
    private _isGameOver = false;
    //判断游戏是否开始.
    public isGameStart = false;

    //定义战斗管理器的单例.
    static _instance:BattleManager = null;
    public static instance(){
        return this._instance;
    }

    onLoad() {
        BattleManager._instance = this;
    }

    //初始化战斗开始前的，动态平衡期的变量.
    public init(){
        this.isGameStart = false;
        //复制敌人到上限.
        this._createEnemies();
    }

    //一般战斗开始前调用，初始化战斗开始后用到的变量.
    public gameStart(){
        this._isGameOver = false;
        this.isGameStart = true;
        for (let i = 0; i < this._allEnemies.length; i++) {
            const mons = this._allEnemies[i];
            mons.readyToAttack();
        }
    }

    //复制敌人，敌人数量不可超过上限，复制敌人有间隔.
    private _createEnemies(){
        if(this._allEnemies && this._allEnemies.length>=this._maxEnemyNum){
            //如果敌人数组不为空，并且长度超过上限，则无需再额外复制敌人，可以退出.
            return;
        }

        //复制一个敌人.
        this._createASigleEnemy();
        //复制敌人的时间间隔之后，再复制下一个敌人.
        this.scheduleOnce(this._createEnemies.bind(this),this._enemyCreateInterval);
    }

    //此函数用于复制一个敌人.
    private _createASigleEnemy(){
        //所有怪物都同几率被复制,先取出数组中一个随机元素的下标.
        const randomIndex = Math.floor(Math.random()*this.enemyPrefabArray.length);
        //根据下标，取出要被复制的随机的怪物的预物体.
        const enemyPrefab = this.enemyPrefabArray[randomIndex];
        //复制敌人.
        let enemy = instantiate(enemyPrefab);
        //将该节点激活.
        enemy.active = true;
        enemy.setParent(this.enemyParent);

        //创建一个新的，空白的怪物控制程序.
        const mons = new Monster();
        //获得怪物身上的MonsterView.
        let view = enemy.getComponent(MonsterView);
        if(!view){
            view = enemy.addComponent(MonsterView);
        }
        
        //将复制出来的敌人加入数组中.
        this._allEnemies.push(mons);

        //敌人的出生点:x坐标在-15,15之间，z坐标在-35,-45之间.
        const randomBornPoint = this._getRandomBornPoint(view.isFlyMonster);
        enemy.setPosition(randomBornPoint);

        mons.init(view);
    }

    //根据边界值，生成一个随机的出生坐标.
    private _getRandomBornPoint(isFlyMonster:boolean){
        //根据最小值和最大值，求一个二者之间的随机值.
        const randomX = Utils.getRandomNumber(this._xMin,this._xMax);
        const randomZ = Utils.getRandomNumber(this._zMin,this._zMax);
        if(isFlyMonster){
            return new Vec3(randomX,1,randomZ);
        }else{
            return new Vec3(randomX,0,randomZ);
        }
        
    }

    //开火，参数pos表示子弹的终点，也可以理解为子弹弹道直线的第二点的坐标(子弹弹道直线的第一点的坐标是枪口)。.
    public fire(pos:Vec3){
        //复制一颗子弹.
        const bullet = instantiate(this.bulletPrefab);
        //设置子弹的父亲.
        bullet.setParent(this.bulletParent);
        bullet.active = true;
        //找到武器下面的一个开火点物体.
        const firePoint = this.weaponNode.getChildByName('firePoint');
        //设置子弹的坐标，让子弹出现在枪口.
        bullet.setPosition(firePoint.worldPosition);
        //让子弹的方向等于开火点物体的方向.
        bullet.setWorldRotation(firePoint.worldRotation);

        let view = bullet.getComponent(BulletView);
        if(!view){
            view = bullet.addComponent(BulletView);
        }
        view.init(pos);
    }

    //玩家被抓住了.
    public playerDead(){
        if(!this._isGameOver){
            this._isGameOver = true;
            //让所有怪物立刻停止前进.
            for (let i = 0; i < this._allEnemies.length; i++) {
                const mons = this._allEnemies[i];
                mons.stopMove();
            }
            //打开失败界面FailPanel.
            UIManager.hideDialog(Constants.UIPage.gamePanel,null);
            UIManager.showDialog(Constants.UIPage.failPanel,null);
        }
    }

    //回收所有怪物.
    public recycleMonsters(){
        for (let i = 0; i < this._allEnemies.length; i++) {
            const mons = this._allEnemies[i];
            mons.dispose();
        }

        this._allEnemies = [];
    }

    public monsterDead(deadMons:Monster){
        for (let i = 0; i < this._allEnemies.length; i++) {
            const mons = this._allEnemies[i];
            if(mons == deadMons){
                //删除怪物数组中的对应下标的怪物.
                this._allEnemies.splice(i,1);
            }
        }
        //复制敌人到上限.
        this._createEnemies();
    }
}
